﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Events;

namespace com.yd.sdk.api
{
    public class AdManager : MonoBehaviour, IAd, IAdListener
    {
        #region 广告相关事件
        public event UnityAction<AdType> HandleAdSucessToLoad;
        public event UnityAction<AdType, string> HandleAdFailedToLoad;
        public event UnityAction<AdType> HandleAdOpened;
        public event UnityAction<AdType, string> HandleAdClosed;
        #endregion
        
        [Header("最大加载重试次数")] [SerializeField] private int _maxFailedReloadCount = 15;
        private int _currentReloadCount = 0;
        public static AdManager Ins;
        
        // [SerializeField] private string _bannerId = "ca-app-pub-3940256099942544/6300978111";
        // [SerializeField] private string _interstitialId = "ca-app-pub-3940256099942544/5224354917";
        // [SerializeField] private string _rewardId = "ca-app-pub-3940256099942544/1033173712";

        private SdkSettings _sdkSettings;

        private void Awake()
        {
            Ins = this;
        }

        // Start is called before the first frame update
        void Start()
        {
            _sdkSettings = Resources.Load<SdkSettings>("SDK_CONFIG");
            if (string.IsNullOrEmpty(_sdkSettings.ADMOB_bannerId) || string.IsNullOrEmpty(_sdkSettings
                                                                      .ADMOB_interstitialId)
                                                                  || string.IsNullOrEmpty(_sdkSettings.ADMOB_rewardId))
            {
                Debug.Log("请前往配置SDK_CONFIG广告");
            }else
                SetAdIds(_sdkSettings.ADMOB_bannerId, _sdkSettings.ADMOB_interstitialId, 
                    _sdkSettings.ADMOB_rewardId);
            
            DontDestroyOnLoad(gameObject);
        }

        // Update is called once per frame
        void Update()
        {

        }

        #region 外部使用

        public void SetTestDeviceIds(string ids)
        {
            #if UNITY_EDITOR
                Debug.Log("SetTestDeviceIds=>Editor not support");        
            #elif UNITY_ANDROID
                JavaAdManager?.Call("SetTestDeviceIds", ids);  
            #elif UNITY_IPHONE || UNITY_IOS
                IOS_SetTestDeviceIds(ids);
            #else
                
            #endif
            
        }

        public void SetAdIds(string bannerId, string interstitialId, string rewardId)
        {
            #if UNITY_EDITOR
                Debug.Log("SetAdIds=>Editor not support");        
            #elif UNITY_ANDROID
                JavaAdManager?.Call("SetAdIds", bannerId, interstitialId, rewardId);
            #elif UNITY_IPHONE || UNITY_IOS
                 IOS_SetAdIds(bannerId, interstitialId, rewardId);           
            #else
                            
            #endif
            
        }

        public void LoadedAd(AdType adType)
        {
             
            #if UNITY_EDITOR
                 Debug.Log("LoadedAd=>Editor not support");        
            #elif UNITY_ANDROID
                Debug.Log("LoadedAd" +JavaAdManager == null);
                JavaAdManager?.Call("LoadedAd",GetAdType2Java(adType));
            #elif UNITY_IPHONE || UNITY_IOS
                IOS_LoadedAd((int)adType);                   
            #else
                                        
            #endif
            
        }

        public bool IsAdAvailable(AdType adType)
        {
            #if UNITY_EDITOR
                Debug.Log("IsAdAvailable=>Editor not support");  
            #elif UNITY_ANDROID
                return JavaAdManager.Call<bool>("IsAdAvailable", GetAdType2Java(adType));
            #elif UNITY_IOS
                IOS_IsAdAvailable((int)adType);
            #else
            #endif

            return false;

        }

        public void ShowBanner(BannerPos pos = BannerPos.Bottom)
        {
            #if UNITY_EDITOR
                Debug.Log("ShowBanner=>Editor not support");  
            #elif UNITY_ANDROID
                if (_currentReloadCount >= _maxFailedReloadCount)
                Debug.Log("超出最大重试次数");
            else
                JavaAdManager?.Call("ShowBanner", GetAdPos2Java(pos));
            #elif UNITY_IOS
                IOS_ShowBanner();
            #else
            #endif
            
        }

        public void ShowInterstitial()
        {
            #if UNITY_EDITOR
                Debug.Log("ShowInterstitial=>Editor not support");  
            #elif UNITY_ANDROID
                JavaAdManager?.Call("ShowInterstitial");
            #elif UNITY_IOS
                IOS_ShowInterstitial();
            #else
            #endif
            
        }

        public void ShowReward()
        {
            #if UNITY_EDITOR
                Debug.Log("ShowReward=>Editor not support");  
            #elif UNITY_ANDROID
                // if (_currentReloadCount >= _maxFailedReloadCount)
                //             Debug.Log("超出最大重试次数");
                //         else
                            JavaAdManager.Call("ShowReward");
            #elif UNITY_IOS
                IOS_ShowReward();
            #else
            #endif                 
        }

        #endregion
        
        
        #region Java回调Wrapper

        
        //调用AdManager的类
        private AndroidJavaObject _javaAdManager;
        private AndroidJavaObject JavaAdManager {
            get
            {
                #if UNITY_EDITOR
                    Debug.Log("JavaAdManager=>Editor not support");        
                #elif UNITY_ANDROID
                    _javaAdManager = _javaAdManager ?? JavaActivity.GetStatic<AndroidJavaObject>("adManager");
                #elif UNITY_IPHONE || UNITY_IOS
                                                        
                #else
                                                        
                #endif
                
                return _javaAdManager;
            }
        }

        private AndroidJavaClass _javaActivity;
        private AndroidJavaClass JavaActivity
        {
            get
            {
                _javaActivity = _javaActivity ?? new AndroidJavaClass(Const.MyUnityPlayerActivity);
                return _javaActivity;
            }
        }
        
        private AndroidJavaObject GetAdType2Java(AdType adType)
        {
            AndroidJavaClass ajc= new AndroidJavaClass("com.yd.sdk.ad.IAd$AdType"); 
            AndroidJavaObject adTyp2java  = null;
            switch (adType)
            {
                case AdType.Banner:
                    adTyp2java = ajc.GetStatic<AndroidJavaObject>("Banner");
                    break;
                case AdType.Interstitial:
                    adTyp2java = ajc.GetStatic<AndroidJavaObject>("Interstitial");
                    break;
                case AdType.Reward:
                    adTyp2java = ajc.GetStatic<AndroidJavaObject>("Reward");
                    break;
            }
            return adTyp2java;
        }

        private AndroidJavaObject GetAdPos2Java(BannerPos pos)
        {
            AndroidJavaClass ajc= new AndroidJavaClass("com.yd.sdk.ad.IAd$BannerPos"); 
            AndroidJavaObject pos2java  = null;
            switch (pos)
            {
                case BannerPos.Bottom:
                    pos2java = ajc.GetStatic<AndroidJavaObject>("Bottom");
                    break;
                case BannerPos.Top:
                    pos2java = ajc.GetStatic<AndroidJavaObject>("Top");
                    break;
            }
            return pos2java;
        }

        private AdType GetAdTypeFromString(string str)
        {
            AdType result = AdType.Banner;
            switch (str)
            {
                case "Banner":
                    break;
                case "Interstitial":
                    result = AdType.Interstitial;
                    break;
                case "Reward":
                    result = AdType.Reward;
                    break;
                default:
                    break;
            }
            return result;
        }

        public void HideAd(AdType adType)
        {
            JavaAdManager?.Call("HideAd", GetAdType2Java(adType));
        }

        public void OnAdSucessToLoad(string message)
        {
            Debug.Log("OnAdSucessToLoad:" + message);
            OnAdSucessToLoad(GetAdTypeFromString(message));
        }

        public void OnAdFailedToLoad(string message)
        {
            Debug.Log("OnAdFailedToLoad:" + message);
            var stringArray = message.Split(':');
            if(stringArray.Length >= 2)
                OnAdFailedToLoad(GetAdTypeFromString(stringArray[0]), stringArray[1]);
            
        }

        public void OnAdOpened(string message)
        {
            Debug.Log("OnAdOpened:" + message);
            OnAdOpened(GetAdTypeFromString(message));
        }

        public void OnAdClosed(string message)
        {
            Debug.Log("OnAdClosed:" + message);
            var stringArray = message.Split(':');
            if(stringArray.Length >= 2)
                OnAdClosed(GetAdTypeFromString(stringArray[0]),stringArray[1]);
        }
        
        #endregion

        

#if UNITY_IOS
        #region IOS
        [DllImport("__Internal")]
        internal extern static void IOS_SetTestDeviceIds(string ids);
        
        [DllImport("__Internal")]
        internal extern static void IOS_SetAdIds(string bannerId,string interstitialId,string rewardId);
        
        [DllImport("__Internal")]
        internal extern static void IOS_LoadedAd(int type);
        
        [DllImport("__Internal")]
        internal extern static bool IOS_IsAdAvailable(int type);
        
        [DllImport("__Internal")]
        internal extern static void IOS_ShowBanner();
        
        [DllImport("__Internal")]
        internal extern static void IOS_ShowInterstitial();
        
        [DllImport("__Internal")]
        internal extern static void IOS_ShowReward();
        
        #endregion
#endif
        
        
        #region C#回调

        public void OnAdSucessToLoad(AdType type)
        {
            //如果成功就重置次数
            _currentReloadCount = 0;
            HandleAdSucessToLoad?.Invoke(type);
        }

        public void OnAdFailedToLoad(AdType type, string message)
        {
            _currentReloadCount++;
            HandleAdFailedToLoad?.Invoke(type,message);
        }

        public void OnAdOpened(AdType type)
        {
            HandleAdOpened?.Invoke(type);
        }

        public void OnAdClosed(AdType type, string reward)
        {
            HandleAdClosed?.Invoke(type,reward);
        }
        #endregion
    }
}



